`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    19:37:46 07/05/2015 
// Design Name: 
// Module Name:    led_drive 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module led_drive(clk,soc_bcd,sout,dout);
  input clk;//clock
  input [11:0] soc_bcd;//input soc data in form of bcd
  output [3:0] sout;//select one seven-segment display
  output [6:0] dout;//output seven segment data
  
  reg [3:0] sout;
  reg [11:0] d1;
  reg [3:0] d2;
  wire [3:0] D1,D2,D3;
  
  assign D1=d1[11:8];//soc hundreds bcd
  assign D2=d1[7:4];//soc tens bcd
  assign D3=d1[3:0];//soc ones bcd 

  //FSM
  parameter S0=3'd0,S1=3'd1,S2=3'd2,S3=3'd3;
  reg [2:0] c_state=S0;//current state
  reg [2:0] n_state;//next state
 
  //current state
  always@(posedge clk)
    c_state<=n_state;

 
  //next state
  always@(c_state)
    case(c_state)
      S0:n_state=S1;
      S1:n_state=S2;
      S2:n_state=S0;
    endcase
 
  //output
  always @(c_state or soc_bcd)
    case(c_state)
      S0:begin
        d1=soc_bcd;
        sout=4'b0100;
        d2=D1;
      end
      S1:begin
        sout=4'b0010;
        d2=D2;
      end
      S2:begin
        sout=4'b0001;
        d2=D3;
      end
    endcase
	 
  decoder_7seg ud1(.A(d2[0]),.B(d2[1]),.C(d2[2]),.D(d2[3]),.SEGA(dout[0]),
.SEGB(dout[1]),.SEGC(dout[2]),.SEGD(dout[3]),.SEGE(dout[4]),.SEGF(dout[5]),.SEGG(dout[6]));
	
endmodule

//7 segment decoder
module decoder_7seg(A,B,C,D,SEGA,
SEGB,SEGC,SEGD,SEGE,SEGF,SEGG);
  input A,B,C,D;
  output SEGA,SEGB,SEGC,SEGD,SEGE,SEGF,SEGG;
  
  wire SEGA,SEGB,SEGC,SEGD,SEGE,SEGF,SEGG;
  reg [1:7] SEGS;
  
  //SEGS
  always @(A,B,C,D) begin
    case({D,C,B,A})
      0: SEGS=7'b1111110;//0
      1: SEGS=7'b0110000;//1
      2: SEGS=7'b1101101;//2
      3: SEGS=7'b1111001;//3
      4: SEGS=7'b0110011;//4
      5: SEGS=7'b1011011;//5
      6: SEGS=7'b1011111;//6
      7: SEGS=7'b1110000;//7
      8: SEGS=7'b1111111;//8
      9: SEGS=7'b1111011;//9 
		default:SEGS=7'b1111110;      
    endcase
  end
  
  //output 7 seg
  assign {SEGA,SEGB,SEGC,SEGD,SEGE,SEGF,SEGG}=SEGS;

endmodule